﻿using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleAlgorithms.Tests
{
    public class C01_SinProblem : ITestable
    {
        public void Test()
        {
            TalorSin(Math.PI / 6, 9);
            // Fun1();
        }

        public double[] GetAllDegrees()
        {
            double[] vs = new double[360 * 100000];
            double delta = 2 * Math.PI / vs.Length;
            for (int i = 0; i < vs.Length; i++)
            {
                vs[i] = Math.Sin(i * delta);
            }

            return vs;
        }

        public void TalorSin(double x, int itemCount)
        {
            int loopCount = 0;
            double y = 0;
            double numerator = x;
            double denomitor = 1;
            double sign = 1;
            do
            {
                y += sign * numerator / denomitor;
                Console.WriteLine($"n={loopCount + 1}:    {y:N20}");

                loopCount++;
                numerator *= x * x;
                denomitor *= 2 * loopCount * (2 * loopCount + 1);
                sign *= -1;
            } while (loopCount < itemCount);



            Console.WriteLine($"sin(x): {Math.Sin(x):N20}");
        }


        public void Fun1()
        {
            // 1.生成1000万个在0~360之间的随机数据
            Console.WriteLine("1.数据生成中...");
            var data = new double[100 * 1000 * 1000];
            double delta = 360 / data.Length;
            for (int i = 0; i < data.Length; i++)
                data[i] = i * delta;

            // 随机洗牌
            Random rand = new Random();
            for (int i = 0; i < 10000; i++)
            {
                int pos = rand.Next(data.Length);
                double temp = data[pos];
                data[pos] = data[i];
                data[i] = temp;
            }

            // 2.直接计算法求解
            Console.WriteLine("2.直接计算...");
            var t1 = DateTime.Now;
            double res1 = 0;
            for (int i = 0; i < data.Length; i++)
                res1 += Math.Sin(data[i]);
            var t2 = DateTime.Now;

            // 3.使用查表法计算
            Console.WriteLine("3.查表法计算...");
            var table = GetAllDegrees();
            var t3 = DateTime.Now;
            double res2 = 0;
            for (int i = 0; i < data.Length; i++)
                res2 += table[(int)(data[i] * 100000)];
            var t4 = DateTime.Now;


            // 4.仅求和
            Console.WriteLine("4.仅求和...");
            var t5 = DateTime.Now;
            double res3 = 0;
            for (int i = 0; i < data.Length; i++)
                res3 += i;
            var t6 = DateTime.Now;

            Console.WriteLine($"直接计算：{(t2 - t1).TotalMilliseconds,4:N0}ms. res1={res1}");
            Console.WriteLine($"查表计算：{(t4 - t3).TotalMilliseconds,4:N0}ms. res2={res2}");
            Console.WriteLine($"输入求和：{(t6 - t5).TotalMilliseconds,4:N0}ms. res3={res3}");
        }
    }
}
